package com.jiubanqingchen.org.login;

import cn.hutool.http.useragent.UserAgent;
import com.jfinal.aop.Aop;
import com.jfinal.aop.Inject;
import com.jfinal.kit.Kv;
import com.jfinal.plugin.activerecord.Record;
import com.jiubanqingchen.framework.base.user.IUser;
import com.jiubanqingchen.framework.exception.WishException;
import com.jiubanqingchen.framework.exception.WishExceptionKey;
import com.jiubanqingchen.framework.security.AuthService;
import com.jiubanqingchen.framework.security.admin.AdminUser;
import com.jiubanqingchen.framework.security.admin.AdminUserService;
import com.jiubanqingchen.framework.support.EncryptionSupport;
import com.jiubanqingchen.framework.support.JwtSupport;
import com.jiubanqingchen.kit.ApplicationKit;
import com.jiubanqingchen.kit.SystemKit;
import com.jiubanqingchen.model.models.LoginLog;
import com.jiubanqingchen.model.models.User;
import com.jiubanqingchen.org.loginLog.LoginLogService;
import com.jiubanqingchen.org.online.OnlineUserService;
import com.jiubanqingchen.org.user.UserService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.servlet.http.HttpServletRequest;

/**
 * 登录服务
 *
 * @author light_dust
 * @since 2020/12/28 17:53
 */
public class LoginService {
    private final static Logger logger = LoggerFactory.getLogger(LoginService.class);
    @Inject
    AuthService authService;

    /**
     * 登录方法 目前支持账号密码登录 后期可以扩展
     *
     * @param kv loginForAccountAndPassword{userAccount,password,loginType}
     */
    public String login(HttpServletRequest request,Kv kv) throws Exception {
        User user = loginForAccountAndPassword(kv.getStr("account"), kv.getStr("password"));
        String userId = user.getUserId();
        String userAccount = user.getUserAccount();
        String userName = user.getUserName();
        //创建adminUser
        AdminUser adminUser= Aop.get(AdminUserService.class).createAdminUser(userId, userAccount, userName);
        String token = JwtSupport.me().createToken(userId);
        //存入在线用户 on-line-user 存入userId userName loginTime token
        Aop.get(OnlineUserService.class).addOnlineUserToCache(userId, userAccount, userName, token);
        //插入登录日志
        if(ApplicationKit.me().getLogLoginEnable()){
            new Thread(() -> {
                try {
                    handleLoginInfo(request, adminUser);
                } catch (Exception e) {
                    logger.error(e.getMessage());
                    e.printStackTrace();
                }
            }).start();
        }

        return token;
    }

    /**
     * 判断用户账号密码是否匹配
     *
     * @param userAccount 用户账号
     * @param password    用户密码
     * @return 是否登录成功
     */
    public User loginForAccountAndPassword(String userAccount, String password) throws Exception {
        User user = Aop.get(UserService.class).getUserForAccount(userAccount);
        if (user == null || !EncryptionSupport.me().decrypPassword(password, user.getUserPassword()))
            throw new WishException(WishExceptionKey.USER_ACCOUNT_OR_PASSWORD_ERROR);
        user.remove("userPassword");//移除密码敏感参数
        return user;
    }

    /**
     * 处理登录信息
     *
     * @param request 请求
     * @param user    用户信息
     */
    private void handleLoginInfo(HttpServletRequest request, IUser user){

        //获取请求UserAgent
        UserAgent userAgent = SystemKit.getUserAgent(request);

        //获取ip信息
        Record ipInfo = SystemKit.getIpInfo(request);

        LoginLog loginLog = new LoginLog();

        //存入登录日志
        loginLog.setLoginIp(ipInfo.getStr("ipAddress")).setLoginArea(ipInfo.getStr("ipArea"))
                .setLoginUserName(user.getUserName()).setOs(userAgent.getOs().getName()).setBrowser(userAgent.getBrowser().getName());
        LoginLogService loginLogService = Aop.get(LoginLogService.class);
        loginLogService.insert(loginLog, new Record(), user);
    }
}
